package pl.koszolko.documentclustering.ui.dendrogram;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.File;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

import javax.imageio.ImageIO;

import org.apache.log4j.Logger;

/**
 * Zapisuje dendrogram do pliku o rozszerzeniu jpg
 * 
 * @author Wojtek
 * 
 */
public class DendrogramSaver {
	private static String FILE_EXTENSION = "jpg";
	private static Logger logger = Logger.getLogger(DendrogramSaver.class);

	public void saveDendrogramToFile(String fileName,
			DendrogramDrawer dendrogramDrawer) {
		RenderedImage rendImage = myCreateImage(dendrogramDrawer);

		try {
			File file = new File(fileName + "." + FILE_EXTENSION);
			ImageIO.write(rendImage, FILE_EXTENSION, file);
		} catch (IOException e) {
			logger.error("Blad zapisu do pliku", e);
		}
	}

	// Returns a generated image.
	public RenderedImage myCreateImage(DendrogramDrawer dendrogramDrawer) {
		int width = (int) (dendrogramDrawer.getMaxX() * 10 + 100 + countOffset(dendrogramDrawer.getMaxTitleLenght()));
		int height = (int) (dendrogramDrawer.getMaxY() * 10 + 30);

		BufferedImage bufferedImage = new BufferedImage(width, height,
				BufferedImage.TYPE_INT_RGB);

		Graphics2D g2d = bufferedImage.createGraphics();
		g2d.setBackground(Color.white);
		g2d.clearRect(0, 0, width, height);

		// rysowanie wezlow
		drawNodes(g2d, dendrogramDrawer.getRoot(), height, dendrogramDrawer.getMaxTitleLenght());

		g2d.dispose();

		return bufferedImage;
	}

	private void drawNodes(Graphics2D g2d, Node root, int height, int maxTitleLenght) {
		g2d.setColor(Color.white);

		List<Node> nodesToDraw = new ArrayList<Node>();
		nodesToDraw.add(root);
		
		int offsetForMaxTitles = countOffset(maxTitleLenght);

		while (!nodesToDraw.isEmpty()) {
			g2d.setColor(Color.black);
			Node node = nodesToDraw.get(0);
			int x = (int) node.getX();
			int y = (int) node.getY();

			Node p = node.getParent();
			int xP = x + 1;
			if (p != null) {
				xP = (int) p.getX();
			}

			g2d.drawLine(offsetForMaxTitles + xP * 10, y * 10,offsetForMaxTitles + x * 10, y * 10);
			g2d.fillOval(offsetForMaxTitles + x * 10 - 3, y * 10 - 3, 5, 6);

			Node childL = node.getChildL();
			Node childR = node.getChildR();
			int yc1;
			int yc2;
			if (childL != null && childR != null) {
				yc1 = (int) childL.getY();
				yc2 = (int) childR.getY();

				g2d.drawLine(offsetForMaxTitles + x * 10, yc1 * 10,offsetForMaxTitles + x * 10, yc2 * 10);
				//wypisanie stopnia podobienstwa
				g2d.drawString(getSimilarityToDraw(node.getSimilarity()), offsetForMaxTitles + x * 10, height - 20);
			} else {
				g2d.fillOval(offsetForMaxTitles + x * 10 - 5, y * 10 - 5, 10, 10);
				g2d.drawString(node.getDocumentTitle(), 10, y* 10 + 5);
			}
			
			// aktualizacja wezlow do rysowania
			nodesToDraw.remove(0);
			if (childL != null && childR != null) {
				nodesToDraw.add(childL);
				nodesToDraw.add(childR);
			}
		}
	}
	
	private int countOffset(int maxTitleLenght) {
		return maxTitleLenght * 6;
	}

	private String getSimilarityToDraw(double similarity) {
		DecimalFormat format = new DecimalFormat("#.##");
		return format.format(similarity);
	}
}
